package coder.nav.schedule;

import cn.hutool.core.bean.BeanUtil;
import coder.nav.config.ApplicationContextConfig;
import coder.nav.model.bo.NavTaskActionBO;
import coder.nav.model.bo.NavTaskBO;
import coder.nav.model.vo.NavTaskActionVO;
import coder.nav.model.vo.NavTaskVO;
import coder.nav.model.vo.setting.NavCashSettingVO;
import coder.nav.schedule.action.NavDataExportAction;
import coder.nav.schedule.action.NavTaskBaseAction;
import coder.nav.schedule.action.NavTaskDayCashAction;
import coder.nav.service.NavSettingService;
import coder.nav.service.NavTaskService;
import coder.nav.utils.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Component
public class NavTaskSchedule {

    @Autowired
    private NavTaskService taskService;
    @Autowired
    private NavSettingService settingService;
    @Autowired
    private NavTaskDayCashAction dayCashAction;
    @Autowired
    private NavDataExportAction dataExportAction;

    /**
     * 执行任务（每分钟轮询一次）
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void executeTask() {
        ApplicationContext applicationContext = ApplicationContextConfig.getApplicationContext();
        Date curDate = new Date();
        // Mysql 配置任务
        List<NavTaskVO> taskList = taskService.getTaskList(null);
        for(NavTaskVO item : taskList) {
            // 将任务加入队列，并更新下次执行时间
            NavTaskBO task = BeanUtil.copyProperties(item, NavTaskBO.class);
            taskService.saveTaskAction(task);
        }
        // Redis 执行任务
        List<NavTaskActionVO> actionList = taskService.getTaskActionList(null);
        for(NavTaskActionVO item : actionList) {
            try {
                if(curDate.before(item.getActionTime())) {
                    continue;
                }
                NavTaskBaseAction action = (NavTaskBaseAction) applicationContext.getBean(FileUtils.lowerCaseName(item.getActionFunction()));
                action.actionTask(BeanUtil.copyProperties(item, NavTaskActionBO.class));
            } catch (Exception ex) {
                // 跳过，不做处理
            }
        }
    }

    /**
     * 数据备份
     */
    @Scheduled(cron = "0 0 0 1 1/1 ?")
    public void executeDatabaseExport() {
        dataExportAction.addTask(1L);
    }

    /**
     * 记账日报
     */
    @Scheduled(cron = "0 59 8 * * ?")
    public void executeDayCash() {
        try {
            // 记账日报
            Map<Long, NavCashSettingVO> map = settingService.getAllUserCashSettingMap();
            map.forEach((userId, setting) -> {
                if(Objects.equals(setting.getOpenDay(), 1)) {
                    dayCashAction.addTask(userId);
                }
            });
        } catch (Exception ex) {
            // 跳过，不做处理
        }
    }

}
